/*
  This example uses the TOgSerialNumber component. The first time
  the program is run, the user is prompted for his serial number
  and release code.

  If the program is being run the first time (as determined by the
  existance of an INI file, a dialog box is displayed showing two
  entry fields: one for the serial number, the other for the release
  code. The user enters the values that you give him for these two
  items. The values are stored in the INI file and the program is
  allowed to run.

  The release code you give the user can be generated by the CODEGEN
  example program. Be sure to select the same type component, the
  key used to compile the application (the one returned in the
  OnGetKey event), Also, if used, make sure the Expires date is
  the same.
*/
//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop

#include "ExSrnmU1.h"
#include "ExSrnmu2.h"
//---------------------------------------------------------------------------
#pragma link "OnGuard"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::OgSerialNumberCode1GetKey(TObject *Sender, TKey &Key)
{
	memcpy(Key, CKey, sizeof(TKey));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::OgSerialNumberCode1GetCode(TObject *Sender, TCode &Code)
{
	String S1;
  // force the INI file to be in the same directory as the application
  TheDir = ExtractFilePath(ParamStr(0));
  int L = TheDir.Length();
  if (L > 3 && TheDir[L] != '\\')
    TheDir = TheDir + '\\';

  /*
  this check helps prevent an empty INI file-> An empty or incomplete
  INI file can cause problems, i->e->, if something goes wrong during
  the initial input of the SN and ReleaseCode, the program could
  not be run again without deleting the INI file-> In a "real world"
  application, you would probably be hiding these values some how and
  would either have to tell the user where to delete things or have a
  utility program to do so->
  */
  if (!FileExists(TheDir + "SNCode.INI"))
    return;

  // open Ini File
  IniFile = new TIniFile(TheDir + "SNCode.INI");
  try {
    // try to read release code
    S1 = IniFile->ReadString("Codes", "SNCode", "");
    IniSNVal = IniFile->ReadInteger("Codes", "SN", 0);

    // convert retrieved string to a code
    HexToBuffer(S1, &Code, sizeof(Code));
  }
  catch (...) {
  	delete IniFile;
    IniFile = 0;
  }
  delete IniFile;
}
//---------------------------------------------------------------------------
int TForm1::GetSNData(String& S)
{
	int Result;
	TCode TC;
  TSNEntryDlg* SNEntryDlg = new TSNEntryDlg(this);
  try {
    // Display new SN and ask for release code
    SNEntryDlg->SNText->Text = "";
    SNEntryDlg->CodeText->Text = "";

    Result = SNEntryDlg->ShowModal();
    if (SNEntryDlg->CodeText->Text == "" ||
        SNEntryDlg->SNText->Text == "")
      Result = mrCancel;
    if (Result == mrCancel) {
      S = "Invalid Code or Cancelled";
      return Result;
    }

    // Check that Release Code was entered correctly
    HexToBuffer(SNEntryDlg->CodeText->Text, &TC, sizeof(TCode));
    if (!IsSerialNumberCodeValid(CKey, TC)) {
      S = "Release code not entered correctly";
      Result = mrCancel;
    }
    else {
      IniFile = new TIniFile(TheDir + "SNCode.INI");
      try {
        /*
        Write SN to IniFile and set a global variable to the value
        of the serial number-> Since, by design, the TOgSerialNumber
        component does not confirm that the SN and ReleaseCode retrieved
        from the INI file are compatible, this value will be used later to
        see if the user has attempted to change the contents of the INI file
        */
        IniSNVal = SNEntryDlg->SNText->Text.ToInt();
        String SNC = SNEntryDlg->CodeText->Text;
        IniFile->WriteInteger("Codes", "SN", IniSNVal);
        IniFile->WriteString("Codes", "SNCode", SNC);
      }
      catch (...) {
        delete IniFile;
        IniFile = 0;
      }
      delete IniFile;
    }
  }
  catch (...) {
	  delete SNEntryDlg;
  	SNEntryDlg = 0;
  }
  delete SNEntryDlg;
  return Result;
}
void __fastcall TForm1::OgSerialNumberCode1Checked(TObject *Sender,
	TCodeStatus Status)
{
  String S;
  int LI;
  switch (Status) {
    case ogValidCode : {
      // check if retrieved Serial Number matches Code
      LI = OgSerialNumberCode1->GetValue();

      if (LI != IniSNVal) {
        Status = ogInvalidCode;
        S = "The serial number has been changed";
      }
      else {
        Label1->Caption = "Serial #: " + String(IniSNVal);
        return;
      }
      break;
    }
    case ogInvalidCode : {
      // if INI file doesn"t exist, presume this is first run
      if (!FileExists(TheDir + "SNCode.INI")) {
        if (GetSNData(S) != mrCancel) {
          // Check the SN/ReleaseCode
          OgSerialNumberCode1->CheckCode(true);
          // must return since line above began a recursive call
          return;
        }
      }
      else
        S = "Invalid Code";
      break;
    }
    case ogCodeExpired : S = "Evaluation period expired";
  }
  ShowMessage(S);
  Application->Terminate();
}
//---------------------------------------------------------------------------